
package com.publicstaticdroid.g2l_interpreter_connect;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.telephony.PhoneNumberUtils;

/**
 * When WaitForCallActivity activity is first started it displays a waiting for connection dialog and registers an instance of SMSCallReciever.
 * When it is activated by a new intent from SMSCallReciever it starts MakeCallActivity.
 * @author Nathan Breit
 */
public class WaitForCallActivity extends Activity {

	private static final int WAIT_FOR_CALL_DIALOG = 0;
	private static final int FAILED_TO_CONNECT_DIALOG = 2;
	private static final int PREEMPTED_DIALOG = 4;
	private ProgressDialog progressDialog;
	private Timer dialogTimer;
	private int MILLISECONDS_TO_WAIT_FOR_CALL = 1000 * 60 * 2; // = 2 minutes

	private int requestID;

	private SMSCallReceiver callReceiver;
	private static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";

	@Override
	public void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);
		
		if(!getIntent().hasExtra("requestID")){
			Log.i("G2L", "request ID is null");
			finish();
			return;
		}
		
		requestID = getIntent().getIntExtra("requestID", -1);
		
		Log.i("G2L", getIntent().toString());
		Log.i("G2L", "rid = " + requestID);
		
		setContentView(R.layout.blank);
		
		showDialog(WAIT_FOR_CALL_DIALOG);

		registerCallReciver();
	}
	/**
	 * Registers the receiver for intercepting SMS call commands (messages beginning with *)
	 */
	private void registerCallReciver() {
		callReceiver = new SMSCallReceiver();
		final IntentFilter theFilter = new IntentFilter();
		theFilter.setPriority(100); //Make sure the call receiver comes first.
		theFilter.addAction(SMS_RECEIVED_ACTION);
		registerReceiver(callReceiver, theFilter);
	}
	private void unregisterCallReciever() {
		// see:
		// http://stackoverflow.com/questions/2682043/how-to-check-if-receiver-is-registered-in-android
		try{
			unregisterReceiver(callReceiver);
			Log.i("G2L", "Unregistering call reciever.");
		}
		catch(IllegalArgumentException e){
			Log.e("G2L", "Unregistering unregistered callReceiver.");
		}
	}
    protected Dialog onCreateDialog(int id) {
    	/* 
    	 * Following the guide here: http://developer.android.com/guide/topics/ui/dialogs.html#ProgressDialog
    	 * 
    	 * There are many things I don't know about dialogs like:
    	 * What happens to them when the activity is paused, or stopped? (Can they still be dismissed by a background thread?)
    	 * Does this method cache previously created dialogs?
    	 * 
    	 * This version of onCreateDialog is Depricated, however it is the only version that works on android 1.6
    	 * 
    	*/
    	AlertDialog.Builder builder;
        switch(id) {
        case WAIT_FOR_CALL_DIALOG:
            progressDialog = new ProgressDialog(WaitForCallActivity.this);
            progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            progressDialog.setMessage("Please wait while we connect you.");
            progressDialog.setCancelable(false);
            return progressDialog;
        case FAILED_TO_CONNECT_DIALOG:
        	builder = new AlertDialog.Builder(this);
        	builder.setMessage("Failed to connect call.")
        	       .setCancelable(true)
        	       .setNeutralButton("Ok", new DialogInterface.OnClickListener() {
        	           public void onClick(DialogInterface dialog, int id) {
        	                finish();
        	           }
        	       });
        	return builder.create();
        case PREEMPTED_DIALOG:
        	builder = new AlertDialog.Builder(this);
        	builder.setMessage("Another interpreter has taken this request.")
        	       .setCancelable(true)
        	       .setNeutralButton("Ok", new DialogInterface.OnClickListener() {
        	           public void onClick(DialogInterface dialog, int id) {
        	                finish();
        	           }
        	       });
        	return builder.create();
        default:
            return null;
        }
    }

    @Override
    protected void onPrepareDialog(int id, Dialog dialog) {
        switch(id) {
        case WAIT_FOR_CALL_DIALOG:
        	
        	dialogTimer = new Timer();
        	
        	dialogTimer.schedule(new TimerTask() {
        		
    			@Override
    			public void run() {
    				runOnUiThread(new Runnable() {
    				
    	    			@Override
    	    			public void run() {
		    				Log.e("G2L", "Dialog timer expired.");
		    				unregisterCallReciever();
							progressDialog.dismiss(); //What happens if I dismiss a non-showing Dialog?
							showDialog(FAILED_TO_CONNECT_DIALOG);
		    				/*
		    				if( progressDialog.isShowing() ){
		    					//If the pd isn't showing then call must have happened right?
		    					//If there is some other way for it to close this needs to change.
		    				}*/
    	    			}
    				});
    			}
    			
    		}, MILLISECONDS_TO_WAIT_FOR_CALL );
    		
        }
        
    }
	//This should only happen when a call command is received.
	@Override
	protected void onNewIntent(Intent intent) {
		super.onNewIntent(intent);
		
		if(intent.hasExtra("numberToCall")){
			Log.i("G2L", "on New intent with " + requestID + " " + intent.getStringExtra("numberToCall"));
			if(requestID == intent.getIntExtra("requestID", -1)){
				//Clean up
				unregisterCallReciever();
				//TODO: There might be an issue with dialog timer going off when it shouldn't.
				dialogTimer.cancel();
				dialogTimer.purge();
				progressDialog.dismiss();
				//Launch MakeCallActivity
				Intent callIntent = new Intent(getApplicationContext(), MakeCallActivity.class);
				//TODO: Why cant I do this?
				//http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_NEW_TASK
				//callIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
				callIntent.setData(Uri.parse(intent.getStringExtra("numberToCall")));
				callIntent.putExtra("requestID", requestID);
				startActivity(callIntent);
				
				finish();
			}
			else{
				Log.e("G2L", "RequestID mismatch in NeedInterpreter: " + requestID + " vs " + intent.getIntExtra("requestID", -1));
			}
		}
		else if(intent.getBooleanExtra("dismiss", false)){
			//Clean up
			unregisterCallReciever();
			//TODO: There might be an issue with dialog timer going off when it shouldn't.
			dialogTimer.cancel();
			dialogTimer.purge();
			progressDialog.dismiss();
			showDialog(PREEMPTED_DIALOG);
		}
		else{
			//This might happen if the user gets another request right while the failure dialog is visible.
			finish();
			Log.e("G2L", "MakeCallActivity relaunched without phone number");
		}
	}
	@Override
	protected void onStop() {
		Log.w("G2L", "onStop");
		super.onStop();
	}
	@Override
	protected void onDestroy() {
		unregisterCallReciever();
		dialogTimer.cancel();
		dialogTimer.purge();
		//unregisterMessageBlocker();
		super.onDestroy();
	}
	
	//This is a nested class so I can call finish from it.
	private class SMSCallReceiver extends SMSReceiver
	{
		@Override
		protected void callCommand(Context c, String phoneNumber, int ccRequestID,
				String phoneNumberToCall) {
			String parsedPhoneNumberToCall = PhoneNumberUtils.extractNetworkPortion(phoneNumberToCall);
			if (PhoneNumberUtils.isGlobalPhoneNumber(parsedPhoneNumberToCall))
			{
				if (PhoneNumberUtils.isEmergencyNumber(parsedPhoneNumberToCall))
				{
					Log.e(LOG_TAG, "Discarding message: we will NOT auto-dial 911");
					return;
				}
			}
			
			parsedPhoneNumberToCall = "tel:" + Constants.BLOCK_CALLER_ID + PhoneNumberUtils.formatNumber(parsedPhoneNumberToCall);
			Intent makeCallIntent = new Intent(c, WaitForCallActivity.class);
			makeCallIntent.addFlags(Intent.FLAG_FROM_BACKGROUND);
			makeCallIntent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
			makeCallIntent.putExtra("numberToCall", parsedPhoneNumberToCall);
			makeCallIntent.putExtra("requestID", ccRequestID);
			c.startActivity(makeCallIntent);
			
			//Note sure if I should launch MakeCallActivity here or in onNewIntent
			
			Log.i(LOG_TAG, "Dialed " + parsedPhoneNumberToCall + " for request id " + ccRequestID);

		}
		@Override
		protected void dismissRequest(Context c, String phoneNumber, int requestID) {
			Intent dismissIntent = new Intent(c, WaitForCallActivity.class);
			dismissIntent.addFlags(Intent.FLAG_FROM_BACKGROUND);
			dismissIntent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
			dismissIntent.putExtra("dismiss", true);
			dismissIntent.putExtra("requestID", requestID);
			c.startActivity(dismissIntent);
			
			Log.i(LOG_TAG, "Dismissing request id " + requestID);

		}
	}
}